<?xml version='1.0' encoding='iso-8859-1'?>
<!doctype html public '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3c.org/1999/xhtml' lang='en-us'>
	<head>
		<title>
			weeder.c
			</title>
		<meta http-equiv='content-type' content='text/html;iso-8859-1'/>
		<meta name='generator' content='motley-tools 1.9.4 13:40:33 Feb 18 2015'/>
		<meta name='author' content='cmaier@cmassoc.net'/>
		<meta name='robots' content='noindex,nofollow'/>
		<link href='toolkit.css' rel='stylesheet' type='text/css'/>
		</head>
	<body>
		<div class='headerlink'>
			[<a href='WatchdogReport.c.html' title=' WatchdogReport.c '>PREV</a>]
			[<a href='toolkit.html' title=' Index '>HOME</a>]
			[<a href='WriteCFG.c.html' title=' WriteCFG.c '>NEXT</a>]
			</div>
<pre>
/*====================================================================*
 *
 *   Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or 
 *   without modification, are permitted (subject to the limitations 
 *   in the disclaimer below) provided that the following conditions 
 *   are met:
 *
 *   * Redistributions of source code must retain the above copyright 
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above 
 *     copyright notice, this list of conditions and the following 
 *     disclaimer in the documentation and/or other materials 
 *     provided with the distribution.
 *
 *   * Neither the name of Qualcomm Atheros nor the names of 
 *     its contributors may be used to endorse or promote products 
 *     derived from this software without specific prior written 
 *     permission.
 *
 *   NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE 
 *   GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE 
 *   COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR 
 *   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
 *   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 *--------------------------------------------------------------------*/

/*====================================================================*
 *
 *   weeder.c - Weeder Solid State Relay Module Controller;
 *
 *   Contributor(s):
 *	Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
 *	Nathaniel Houghton &lt;nhoughto@qca.qualcomm.com&gt;
 *	Mathieu Olivari &lt;mathieu@qca.qualcomm.com&gt;
 *
 *--------------------------------------------------------------------*/

/*====================================================================*
 *   system header files;
 *--------------------------------------------------------------------*/

#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;ctype.h&gt;

#if defined (__linux__)
#	include &lt;termios.h&gt;
#elif defined (__APPLE__)
#	include &lt;termios.h&gt;
#elif defined (__OpenBSD__)
#	include &lt;termios.h&gt;
#elif defined (WIN32)
#	include &lt;windows.h&gt;
#else
#error &quot;Unknown Environment&quot;
#endif

/*====================================================================*
 *   custom header files;
 *--------------------------------------------------------------------*/

#include &quot;../tools/getoptv.h&quot;
#include &quot;../tools/putoptv.h&quot;
#include &quot;../tools/version.h&quot;
#include &quot;../tools/number.h&quot;
#include &quot;../tools/symbol.h&quot;
#include &quot;../tools/timer.h&quot;
#include &quot;../tools/files.h&quot;
#include &quot;../tools/flags.h&quot;
#include &quot;../tools/error.h&quot;

/*====================================================================*
 *   custom source files;
 *--------------------------------------------------------------------*/

#ifndef MAKEFILE
#include &quot;../tools/getoptv.c&quot;
#include &quot;../tools/putoptv.c&quot;
#include &quot;../tools/version.c&quot;
#include &quot;../tools/uintspec.c&quot;
#include &quot;../tools/synonym.c&quot;
#include &quot;../tools/todigit.c&quot;
#include &quot;../tools/error.c&quot;
#endif

/*====================================================================*
 *   program constants;
 *--------------------------------------------------------------------*/

#define WEEDER_UNITS &quot;BA&quot;
#define WEEDER_LEDS 5
#define WEEDER_BITS 7
#define WEEDER_WAIT 25
#define WEEDER_ECHO 0
#define WEEDER_MODE 1

#define WEEDER_BUFFER_LENGTH 10
#define WEEDER_STRING_LENGTH 15

#ifdef WIN32
#	define WEEDER_PORT &quot;com1:&quot;
#else
#	define WEEDER_PORT &quot;/dev/ttyS0&quot;
#endif

#define WEEDER_SILENCE (1 &lt;&lt; 0)
#define WEEDER_VERBOSE (1 &lt;&lt; 1)
#define WEEDER_DISPLAY (1 &lt;&lt; 2)
#define WEEDER_NEWLINE (1 &lt;&lt; 2)

/*====================================================================*
 *   program variables;
 *--------------------------------------------------------------------*/

static struct _term_ const modes [] =

{
	{
		&quot;off&quot;,
		&quot;0&quot;
	},
	{
		&quot;on&quot;,
		&quot;1&quot;
	}
};

static char buffer [WEEDER_BUFFER_LENGTH];
static char string [WEEDER_STRING_LENGTH];
static signed length = 0;
static signed offset = 0;

/*====================================================================*
 *
 *   void function1 (struct _file_ * port, char const * units, unsigned wait, unsigned echo);
 *
 *   send echo command to Weeder Solid State Relay modules B then A;
 *   Standard Atheros relay modules were wired in reverse order for
 *   some reason;
 *
 *--------------------------------------------------------------------*/

static void function1 (struct _file_ * port, char const * units, unsigned wait, unsigned echo)

{
	extern char buffer [];
	extern signed length;
	while (*units)
	{
		length = 0;
		buffer [length++] = *units++;
		buffer [length++] = 'X';
		buffer [length++] = '0' + (echo &amp; 1);
		buffer [length++] = '\r';
		if (write (port-&gt;file, buffer, length) != length)
		{
			error (1, errno, FILE_CANTSAVE, port-&gt;name);
		}
		SLEEP (wait);
	}
	return;
}

/*====================================================================*
 *
 *   void function2 (struct _file_ * port, char const * units, unsigned wait, unsigned mode, unsigned data);
 *
 *   send write command to Weeder Solid State Relay modules B then A
 *   because Qualcomm Atheros relay modules are wired in reverse order
 *   for some reason;
 *
 *--------------------------------------------------------------------*/

static void function2 (struct _file_ * port, char const * units, unsigned wait, unsigned mode, unsigned data)

{
	extern char buffer [WEEDER_BUFFER_LENGTH];
	extern signed length;
	length = 0;
	buffer [length++] = *units++;
	buffer [length++] = 'W';
	buffer [length++] = '0' + (mode &amp; 1);
	buffer [length++] = '0';
	buffer [length++] = '0';
	while (length &lt; WEEDER_BITS)
	{
		buffer [length++] = '0' + (data &amp; 1);
		data &gt;&gt;= 1;
	}
	buffer [length++] = '\r';
	if (write (port-&gt;file, buffer, length) != length)
	{
		error (1, errno, FILE_CANTSAVE, port-&gt;name);
	}
	SLEEP (wait);
	length = 0;
	buffer [length++] = *units++;
	buffer [length++] = 'W';
	while (length &lt; WEEDER_BITS)
	{
		buffer [length++] = '0' + (data &amp; 1);
		data &gt;&gt;= 1;
	}
	buffer [length++] = '\r';
	if (write (port-&gt;file, buffer, length) != length)
	{
		error (1, errno, FILE_CANTSAVE, port-&gt;name);
	}
	SLEEP (wait);
	return;
}

/*====================================================================*
 *
 *   void function3 (struct _file_ * port, char const * units, unsigned wait);
 *
 *   read weeder solid state controller and display settings on the
 *   console as attenuation;
 *
 *--------------------------------------------------------------------*/

static void function3 (struct _file_ * port, char const * units, unsigned wait)

{
	extern char buffer [WEEDER_BUFFER_LENGTH];
	extern char string [WEEDER_STRING_LENGTH];
	extern signed length;
	extern signed offset;
	unsigned number = 0;
	memset (string, 0, sizeof (string));
	for (offset = 0; *units; offset += WEEDER_LEDS)
	{
		length = 0;
		buffer [length++] = *units++;
		buffer [length++] = 'R';
		buffer [length++] = '\r';
		if (write (port-&gt;file, buffer, length) != length)
		{
			error (1, errno, FILE_CANTSAVE, port-&gt;name);
		}
		SLEEP (wait);
		memset (buffer, 0, sizeof (buffer));
		if (read (port-&gt;file, buffer, WEEDER_LEDS + 2) == -1)
		{
			error (1, errno, FILE_CANTREAD, port-&gt;name);
		}
		SLEEP (wait);
		memcpy (&amp;string [offset], &amp;buffer [1], WEEDER_LEDS);
	}
	while (offset-- &gt; 3)
	{
		number &lt;&lt;= 1;
		number |= string [offset] - '0';
	}
	printf (&quot;%d\n&quot;, number);
	return;
}

/*====================================================================*
 *
 *   int main (int argc, char const * argv []);
 *
 *--------------------------------------------------------------------*/

int main (int argc, char const * argv [])

{
	static char const * optv [] =
	{
		&quot;e:m:o:p:iqrvw:&quot;,
		&quot;&quot;,
		&quot;Weeder Solid State Relay Module Controller&quot;,
		&quot;e n\techo is (n) [&quot; LITERAL (WEEDER_ECHO) &quot;]&quot;,
		&quot;m n\tmode is (n) [&quot; LITERAL (WEEDER_MODE) &quot;]&quot;,
		&quot;o s\tunit order is (s) [&quot; WEEDER_UNITS &quot;]&quot;,
		&quot;p f\tport is (f) [&quot; WEEDER_PORT &quot;]&quot;,
		&quot;q\tquiet mode&quot;,
		&quot;r\tread attenuator value&quot;,
		&quot;v\tverbose mode&quot;,
		&quot;w n\twait (n) millseconds [&quot; LITERAL (WEEDER_WAIT) &quot;]&quot;,
		(char const *) (0)
	};
	struct _file_ port =
	{
		-1,
		WEEDER_PORT
	};

#if defined (WIN32)

	HANDLE hSerial;
	DCB dcbSerial =
	{
		0
	};

#else

	struct termios termios;

#endif

	char const * units = WEEDER_UNITS;
	unsigned wait = WEEDER_WAIT;
	unsigned echo = WEEDER_ECHO;
	unsigned mode = WEEDER_MODE;
	unsigned data = 0;
	flag_t flags = (flag_t)(0);
	signed c;
	optind = 1;
	if (getenv (&quot;WEEDER&quot;))
	{
		port.name = strdup (getenv (&quot;WEEDER&quot;));
	}
	while ((c = getoptv (argc, argv, optv)) != -1)
	{
		switch (c)
		{
		case 'e':
			echo = (unsigned)(uintspec (synonym (optarg, modes, SIZEOF (modes)), 0, 1));
			break;
		case 'm':
			mode = (unsigned)(uintspec (synonym (optarg, modes, SIZEOF (modes)), 0, 1));
			break;
		case 'n':
			_setbits (flags, WEEDER_NEWLINE);
			break;
		case 'o':
			units = optarg;
			break;
		case 'p':
			port.name = optarg;
			break;
		case 'w':
			wait = (unsigned)(uintspec (optarg, 5, 100));
			break;
		case 'q':
			_setbits (flags, WEEDER_SILENCE);
			break;
		case 'r':
			_setbits (flags, WEEDER_DISPLAY);
			break;
		case 'v':
			_setbits (flags, WEEDER_VERBOSE);
			break;
		default:
			break;
		}
	}
	argc -= optind;
	argv += optind;
	if ((argc) &amp;&amp; (* argv))
	{
		data = (unsigned)(uintspec (* argv, 0, 0x7F));
	}

#if defined (WIN32)

	hSerial = CreateFile (port.name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (hSerial == INVALID_HANDLE_VALUE)
	{
		error (1, errno, FILE_CANTOPEN, port.name);
	}
	dcbSerial.DCBlength = sizeof (dcbSerial);
	if (!GetCommState (hSerial, &amp;dcbSerial))
	{
		error (1, 0, FILE_CANTREAD &quot; state&quot;, port.name);
	}
	dcbSerial.BaudRate = CBR_9600;
	dcbSerial.ByteSize = 8;
	dcbSerial.StopBits = ONESTOPBIT;
	dcbSerial.Parity = NOPARITY;
	if (!SetCommState (hSerial, &amp;dcbSerial))
	{
		error (1, 0, FILE_CANTSAVE, port.name);
	}
	CloseHandle (hSerial);
	if ((port.file = open (port.name, O_BINARY | O_RDWR)) == -1)
	{
		error (1, errno, FILE_CANTOPEN &quot; state&quot;, port.name);
	}

#else

	if ((port.file = open (port.name, O_RDWR|O_NOCTTY|O_NDELAY)) == -1)
	{
		error (1, 0, FILE_CANTOPEN, port.name);
	}
	tcgetattr (port.file, &amp;termios);
	termios.c_cflag = CS8;
	cfsetospeed (&amp;termios, B9600);
	tcsetattr (port.file, TCSANOW, &amp;termios);

#endif

	function1 (&amp;port, units, wait, echo);
	if ((argc) &amp;&amp; (* argv))
	{
		function2 (&amp;port, units, wait, mode, data);
	}
	if (_anyset (flags, WEEDER_DISPLAY))
	{
		function3 (&amp;port, units, wait);
	}
	close (port.file);
	exit (0);
}


</pre>
		<div class='footerlink'>
			[<a href='WatchdogReport.c.html' title=' WatchdogReport.c '>PREV</a>]
			[<a href='toolkit.html' title=' Index '>HOME</a>]
			[<a href='WriteCFG.c.html' title=' WriteCFG.c '>NEXT</a>]
			</div>
		</body>
	</html>
